/*
 ============================================================================
 Name		: LlcpSendHandler.cpp
 Author	  : 
 Version	 : 1.0
 Copyright   : 
 Description : CLlcpSendHandler implementation
 ============================================================================
 */

#include "LlcpSendHandler.h"
#include "P2PMessageSupplier.h"

#include <llcpconnorientedtransporter.h>
#include "Log.h"

CLlcpSendHandler::CLlcpSendHandler(MLlcpConnOrientedTransporter* aTransporter,
		MP2PMessageSupplier* aMessageSupplier) :
	CActive(EPriorityStandard), // Standard priority
	iState(EIdle),
	iTransporter(aTransporter),
	iMessageSupplier(aMessageSupplier)
	{
	}

CLlcpSendHandler* CLlcpSendHandler::NewLC(MLlcpConnOrientedTransporter* aTransporter,
		MP2PMessageSupplier* aMessageSupplier)
	{
	CLlcpSendHandler* self = new (ELeave) CLlcpSendHandler(aTransporter,
			aMessageSupplier);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CLlcpSendHandler* CLlcpSendHandler::NewL(MLlcpConnOrientedTransporter* aTransporter,
		MP2PMessageSupplier* aMessageSupplier)
	{
	CLlcpSendHandler* self = CLlcpSendHandler::NewLC(aTransporter,
			aMessageSupplier);
	CleanupStack::Pop(); // self;
	return self;
	}

void CLlcpSendHandler::ConstructL()
	{
	CActiveScheduler::Add(this); // Add to scheduler
	iState = EConnecting;
	iTransporter->Connect(iStatus);
	SetActive(); // Tell scheduler a request is active
	}

CLlcpSendHandler::~CLlcpSendHandler()
	{
	Cancel(); // Cancel any request, if outstanding
	// Delete instance variables if any
	}

void CLlcpSendHandler::DoCancel()
	{
	switch (iState)
		{
		case EIdle:
			{
			break;
			}
		case EConnecting:
			{
			iTransporter->ConnectCancel();
			break;
			}
		case ETransmitting:
			{
			iTransporter->TransmitCancel();
			break;
			}
		}
	iState = EIdle;
	}

//void CLlcpSendHandler::SendMessageL(const TDesC8& aMessage)
//	{
//	Cancel(); // Cancel any request, just to be sure
//	iState = EConnecting;
//	iMessage.Close();
//	iMessage.CreateL(aMessage);
//	iTransporter->Connect(iStatus);
//	SetActive(); // Tell scheduler a request is active
//	}

void CLlcpSendHandler::SendNextMessage()
	{
	if (IsActive())
		{
		LOG1(_L8("Sender, already sending."));
		return;
		}
	HBufC8* payload = iMessageSupplier->GetNextMessagePayload();
	if ( payload )
		{
		iMessage.Close();
		iMessage.Create(payload->Length());
		iMessage.Copy(*payload);
		delete payload;
		iTransporter->Transmit(iStatus, iMessage);
		iState = ETransmitting;
		LOG2(_L8("Sender, connected, transmitting"), iStatus.Int());
		SetActive();
		}
	else
		{
		LOG1(_L8("Sender, nothing to send."));
		}
	}

void CLlcpSendHandler::RunL()
	{
	switch (iState)
		{
		case EConnecting:
			{
			if (iStatus == KErrNone)
				{
				LOG1(_L8("Sender, sending"));
				SendNextMessage();
				return;
				}
			else
				{
				LOG2(_L8("Sender, connect error: %d\n"), iStatus.Int());
				iStatus == EError;
				return;
				}
			}
		case ETransmitting:
			{
			iMessageSupplier->SendResult(iStatus.Int());
			if (iStatus == KErrNone)
				{
				LOG1(_L8("Sender, transmit done"));
				SendNextMessage();
//				iTransporter->Disconnect();
				return;
				}
			else
				{
				LOG2(_L8("Sender, transmit error: %d\n"), iStatus.Int());
				iStatus == EError;
				return;
				}
			}
		}
	}

TInt CLlcpSendHandler::RunError(TInt aError)
	{
	return aError;
	}
